using UnityEngine;
using System.Collections;
using ResourceClasses;
using GeneralStorageClasses;

namespace TileMapClasses
{
	/// <summary>
	/// Tile selected event.
	/// </summary>
	public delegate void tileSelectedEvent (bool state,int ID);
	/// <summary>
	/// Tile control event.
	/// </summary>
	public delegate void tileControlEvent (int state,int tileID);

	/// <summary>
	/// Tile placed in the overworld.
	/// </summary>
	public class Tile
	{
		//Prefab and colours
		private GameObject potato;
		private TileColours colours;

		//Class Variables
		private int terrainType; 				//determining the terrain of the map 0-9
		//0 = plains
		// 1 = ancient forests


		private Resource resources; 			//resource production per turn
		private Reward rewards;					//Rewards for taking the tile
		private int controlled;					//Who controlls the variable 0-uncontrolled, 1-player, 2-titan
		private bool selected; 					//if the tile selected
		private Story story;					//Story of each tile
		private int tileID;						//Tile's ID
		private int population;
		private Renderer render;
		private bool ffs;
		//Events for selection and updating who owns it
		public static event tileSelectedEvent tileSelected;
		public static event tileControlEvent tileControlUpdate;

		/// <summary>
		/// Initializes a new instance of the <see cref="TileMapClasses.Tile"/> class.
		/// </summary>
		/// <param name="prefab">Prefab.</param>
		public Tile (GameObject prefab)
		{
			//Init Default values
			tileID = -1;
			rewards = null;
			controlled = 0;
			terrainType = 0;
			population = 0;
			selected = false;
			story = new Story ();
		
			//Store the prefab as a passed potato
			potato = prefab;

			//Get colours from the prefab(workaround for inspector on non-mono classes)
			colours = potato.GetComponent<TileColours> ();

			ffs = true;
		}

		/// <summary>
		/// Releases unmanaged resources and performs other cleanup operations before the <see cref="TileMapClasses.Tile"/> is
		/// reclaimed by garbage collection.
		/// </summary>
		~Tile ()
		{
			Debug.LogError ("Tile deleted");
		}

		/// <summary>
		/// Hide this instance.
		/// </summary>
		public void Hide ()
		{
			ffs = false;
		}

		/// <summary>
		/// Unhide this instance.
		/// </summary>
		public void Unhide ()
		{
			ffs = true;
		}


		public void Update ()
		{
			if (ffs) {
				if (controlled == 0) {
					potato.renderer.material.color = colours.uncontrolledColor;
				} else if (controlled == 1) {
					potato.renderer.material.color = colours.playerColor;
				} else if (controlled == 2) {
					potato.renderer.material.color = colours.titanColor;
				} else {
					potato.renderer.material.color = Color.black;
				}

				//FIXME: Change to Pysics.Raycast
				Ray raycast = Camera.main.ScreenPointToRay (Input.mousePosition);
				RaycastHit hitInfo;
			
				if (potato.collider.Raycast (raycast, out hitInfo, Mathf.Infinity)) {

					//Highlight the tile using the correct colour
					potato.renderer.material.color = colours.highlightColor;

					//When mouse is clicked select the tile
					if (Input.GetMouseButtonDown (0)) {
						Selected = true;
					}
				}

				//putting on material if selected, done externally and at the end so the refresh doesn't override
				if (selected) { 
					potato.renderer.material.color = colours.selectionColor;
				}

				//deselecting tile when right click
				if (Input.GetMouseButtonDown (1)) { 
					Selected = false;
				}
			}
		}

		/*--------------------------------------------------* 
	 * -------------------ACCESSORS---------------------
	 * -------------------------------------------------*/

		/// <summary>
		/// Gets or sets the type of the terrain.
		/// </summary>
		/// <value>The type of the terrain.</value>
		public int TerrainType {
			get {
				return terrainType;
			}
			set {
				terrainType = value;
			}
		}

		/// <summary>
		/// Gets or sets the res acc.
		/// </summary>
		/// <value>The res acc.</value>
		public Resource resAcc {
			get {
				return resources;
			}
			set {
				resources = value;
			}
		}

		/// <summary>
		/// Gets or sets the story object.
		/// </summary>
		/// <value>The story object.</value>
		public Story storyObj {
			get {
				return story;
			}
			set {
				story = value;
			}
		}
	
		/// <summary>
		/// Gets or sets the controlled.
		/// </summary>
		/// <value>The controlled.</value>
		public int Controlled {
			get {
				return controlled;
			}
			set {
				controlled = value;
				if (tileControlUpdate != null) {
					tileControlUpdate (value, TileID);
				}
			}
		}

		/// <summary>
		/// Gets or sets a value indicating whether this <see cref="TileMapClasses.Tile"/> is selected.
		/// </summary>
		/// <value><c>true</c> if selected; otherwise, <c>false</c>.</value>
		public bool Selected {
			get {
				return selected;
			}
			set {
				selected = value;
				if (tileSelected != null) {
					tileSelected (value, TileID);
				}
			}
		}

		/// <summary>
		/// Sets a value indicating whether this <see cref="TileMapClasses.Tile"/> seleted no event.
		/// </summary>
		/// <value><c>true</c> if seleted no event; otherwise, <c>false</c>.</value>
		public bool SeletedNoEvent {
			set {
				selected = value;
			}
		}

		/// <summary>
		/// Gets or sets the tile I.
		/// </summary>
		/// <value>The tile I.</value>
		public int TileID {
			get {
				return tileID;
			}
			set {
				tileID = value;
			}
		}

		/// <summary>
		/// Gets or sets the rewards.
		/// </summary>
		/// <value>The rewards.</value>
		public Reward Rewards {
			get {
				return rewards;
			}
			set {
				Rewards = value;
			}
		}

		/// <summary>
		/// Gets or sets the potatas.
		/// </summary>
		/// <value>The potatas.</value>
		public GameObject potatas {
			get {
				return potato;
			}
			set {
				potato = value;
			}
		}

		/// <summary>
		/// Gets or sets the population.
		/// </summary>
		/// <value>The population.</value>
		public int Population {
			get {
				return population;
			}
			set {
				population = value;
				if (population < 100) {
					population = 0;
				} else if (population > 100000) {
					population = 100000;
				}
			}
		}

		/// <summary>
		/// Gets the worth.
		/// </summary>
		/// <value>The worth.</value>
		public int Worth {
			get {
				int worth = (population / 100) * (controlled + 1);
				return (worth);
			}
		}

		/// <summary>
		/// Returns a <see cref="System.String"/> that represents the current <see cref="TileMapClasses.Tile"/>.
		/// </summary>
		/// <returns>A <see cref="System.String"/> that represents the current <see cref="TileMapClasses.Tile"/>.</returns>
		public override string ToString ()
		{
			return terrainType + "\n" + resources.ToString () + "\n" + controlled + "\n" + selected + "\n" + tileID;
		}
	}
}
